﻿/***********************************************
【名称】 CTL 数据转换器
【更新历史】
2021/10/01 初始化此类。

数据库类型：MSS2012
IP地址：10.0.21.102
数据库：QS_727_DB
mstsc账号：Administrator, Ts#00102
数据位置：dbo.Act_Test_Data


【为CTL数据库主表设置主键】
dbo.Act_Test_Data.ID 缺少主键，由于数据量比较大，容易超时，建议使用以下方法（设置主键超时解决办法）：
1、设置主键
2、导出脚本
3、设置服务器→连接→超时 为0.
参考网站:https://blog.csdn.net/u011792365/article/details/51459270

************************************************/
using DataConverter.Utils;
using QDAS;
using System.Text;
namespace DataConverter.Core
{
    public class C2021T03_CTL : ConvertBase
    {
        /// <summary>
        /// 对Code表24小时更新1次。
        /// </summary>
        DateTime lastCodeUpdateTime = new DateTime(2021, 1, 1);

        Dictionary<string, string> codes = new Dictionary<string, string>();

        //string configFile = @"./configs/C2021T03_CTL_Properties.csv";
        string configFile = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "configs/C2021T03_CTL_Properties.csv"));
        Dictionary<string, Chs> dics = new Dictionary<string, Chs>();


        struct Chs
        {
            public string code;
            public string testItem;
            public string k2101;
            public string k2110;
            public string k2111;
            public string consoleType;
            public string remark;

            /// <summary>
            /// 以 DF727B17_12 这样的格式返回。
            /// </summary>
            /// <returns></returns>
            internal string type_code()
            {
                return consoleType + "_" + code;
            }
        }

        public C2021T03_CTL()
        {
            CompanyName = "CTL 转换器";
            TableName =   "Act_Test_Data";
            TableIDName = "ID";
            Version = "beta0.1.0 Released Date: 2021/11/15 Inner Name: C2021T03_CTL";
            DebugMode = true;
        }

        public override bool OnStart()
        {
            LoadConfigs();
            if (DebugMode)
            {
                SqlConnectionString = "Data Source = 112.74.87.167;Initial Catalog = QS_727_DB;User ID = sa; Password = root00;";
                Console.WriteLine(SqlConnectionString);
                sm = new SQLManager(SqlConnectionString);
            }
            Console.WriteLine("100");
            return base.OnStart();
        }

        private void LoadConfigs()
        {
            dics.Clear();
            Console.WriteLine(configFile);
            foreach (var item in File.ReadAllLines(configFile, Encoding.UTF8))
            {
                var line = item.Trim();
                if (line.Length == 0)
                    continue;
                var items = line.Split(',');
                if (items.Length>2 && items[1].Trim().Length > 0)
                {
                    // Code	TestItem	名称值（K2101）	下限值（K2110）	上限值（K2111）	备注
                    // 27  I O 测试_拨叉1位置传感器     450 4550
                    // 2021/12/21更新，添加一列
                    // Code,ChName,名称值（K2101）,下限值（K2110）,上限值（K2111）,Type,备注
                    //  27,I O 测试_拨叉1位置传感器,,450,4550,DF727B17,
                    var chs = new Chs()
                    {
                        code = items[0].Trim(),
                        testItem = items[1].Trim(),
                        k2101 = items[2].Trim(),
                        k2110 = items[3].Trim(),
                        k2111 = items[4].Trim(),
                        consoleType = items[5].Trim(),
                        remark = items[6].Trim()
                    };
                    if (!dics.ContainsKey(chs.code))
                        dics.Add(chs.type_code(), chs);
                }
            }

            // Console.WriteLine(dics.Count);
        }

        public override void OneLoop_Prepare()
        {
            if ((DateTime.Now - lastCodeUpdateTime).TotalHours > 24)
            {
                sm.CommandText = "SELECT Code,TestItem FROM QS_727_DB.dbo.Act_Test_Code";
                var data = sm.GetStrings();
                if (data != null)
                    foreach (var row in sm.GetStrings())
                        if (!codes.Keys.Contains(row[0]))
                            codes.Add(row[0], row[1]);
                lastCodeUpdateTime = DateTime.Now;
            }
            base.OneLoop_Prepare();
        }

        public override void OneLoop_Process()
        {

            LastResID = LastResID < 147770870 ? 147770870 : LastResID;

            sm.CommandText = "SELECT ID,[Type],SN,Code,TestItem,TestValue,Unit,IsOK,TestTime,DeviceCode,Producer,Sources";
            sm.CommandText += $" FROM Act_Test_Data WHERE ID between {LastResID} and {LastResID + BatchCount}";
            //sm.CommandText += $" FROM Act_Test_Data WHERE ID >= {LastResID} and ID < {LastResID + BatchCount}";
            var data = sm.GetStrings();

            // 按设备唯一编号(如S40135C15000100BN0400LB00234)进行分组
            Dictionary<string, List<string[]>> groups = new Dictionary<string, List<string[]>>();
            List<string> keys = new List<string>();

            Console.WriteLine("201");

            foreach (var row in data)
            {
                var key = row[2]; // 设备编号
                if (!groups.ContainsKey(key))
                {
                    keys.Add(key);
                    groups.Add(key, new List<string[]>());
                }
                groups[key].Add(row);
            }

            //foreach (var key in keys)
            //{
            //    Console.WriteLine(key + ", " + groups[key].Count);
            //}

            //LastResID = int.Parse(groups[keys.Last()][0][0]);
            //Common.AddLog("TRACE: LastResID=" + LastResID);
            //  0. ID          -        92
            //  1. Type        K1001    DF727A53
            //  2. SN          K1009    S40135C15000100BN0400LB00234   
            //  3. Code        K2001    1258
            //  4. TestItem    K2002    离合器PI数据自学习(上升与下降)
            //  5. TestValue   K0001    未测试
            //  6. Unit        K2142    - , ℃, cbar, cmm, dNm, L, mA, mV, N, Nm, rpm, s
            //  7. IsOK        -        -
            //  8. TestTime    K0004    2020-02-20 09:25:13
            //  9. DeviceCode  K0012    0071-1
            // 10. Producer    ?        CTL
            // 11. Sources     Check
            // 按组进行处理
            // ID	Type	SN	Code	TestItem	TestValue	Unit	IsOK	TestTime	DeviceCode	Producer	Sources
            // 92  DF727A53 S40135C15000100BN0400LB00234    1258    离合器PI数据自学习(上升与下降)   未测试----  2020/2/20 9:25  0071-1  CTL Check
            // 93  DF727A53 S40135C15000100BN0400LB00234    24  加油_加油量 已加油 L OK  2020/2/20 9:25  0071-1  CTL Check

            for (int i = 0; i < keys.Count; i++)
            {
                var datai = groups[keys[i]];
                datai.OrderBy(d => d[3]);  // 根据编号排序。

                if (datai.Count == 0)
                    continue;

                QFile qf = new QFile();
                qf[1001] =  datai[0][1];
                qf[1002] =  datai[0][1];
                qf[1086] = "DCT-0200"; // 2021/12/27 可能是 datai[0][9];
                qf[1206] = "CTL";
                qf[1203] = "预检";

                foreach (var item in datai)
                {
                    /* 1. 先对数据进行验证，如果数据错了，不添加参数。 */
                    // 如果是空值则继续下个循环
                    string valuestr = item[5];
                    if (string.IsNullOrEmpty(valuestr))
                        continue;

                    // 用于处理每行的数值。
                    List<double> values = new List<double>();

                    // 单值的情况
                    if (double.TryParse(item[5], out double testvalue))
                    {
                        values.Add(testvalue);
                    }
                    // 多值的情况
                    else if (valuestr.Contains(","))
                    {
                        foreach (var str in valuestr.Split(','))
                            if (double.TryParse(str, out double v0))
                                values.Add(v0);
                    }
                    // 解析失败继续下一循环
                    else
                    {
                        continue;
                    }

                    // 如果没有数据，则继续下一循环。
                    if (values.Count == 0)
                        continue;

                    /* 2. 开始提取参数和测量数据并转换为DFQ文件 */
                    // 添加参数层
                    QCharacteristic qc = qf.AddQCharacteristic();
                    qc[2001] = item[3];
                    qc[2002] = item[4]; // 这项就是测量的名称
                    if (dics.ContainsKey(item[1]+"_"+item[3]))
                    {
                        var chi = dics[item[1] + "_" + item[3]];
                        qc[2101] = chi.k2101;
                        qc[2110] = chi.k2110;
                        qc[2111] = chi.k2111;
                    }
                    qc[2142] = item[6];

                    // 处理数值层
                    var b1 = DateTime.TryParse(item[8], out DateTime testTime);
                    foreach (double value in values)
                    {
                        var di = qc.AddItem();
                        di.value = value;
                        di.date = b1 ? testTime : DateTime.MinValue;

                        // 软件版本号，仅在code=26时取testValue的值
                        if (item[3]=="26")
                            di[0009] = testvalue;

                        // 检测设备catalog, 转换规则：0071-001 --> 总成预检测-CTL1
                        if (item[9].Contains("0071-"))
                        {
                            if (int.TryParse(item[9].Replace("0071-", ""), out int cid))
                            {
                                di[0012] = "110501" + (cid-1);
                                di[0010] = "110501" + (cid-1);
                            }
                        }
                        di[0014] = item[2];// 零件ID
                    }
                }
                Console.WriteLine("202");
                SaveToDFQ(qf, OutputDirectory, "CTL_" + DateTime.Now.ToString("yyyyMMdd_HHmmss.fff"));
            }

        }

    }
}
